package top.malaoshi.data;

import java.util.ArrayList;
import java.util.List;

/**
 * 封装一行数据
 * @author mym
 *
 */
public class DataRow {
    /**
     * 一行数据
     */
    protected List<Object> dataList;

    private DataTable dt;
    /**
     * 标识一行记录，类似oracle的rowid
     * 将DataRow添加到DataTable后，才会生成rowid
     */
    private Integer rowid;

    protected DataRow(int columnNum){
        dataList =new ArrayList<>(columnNum);
        for(int i=0;i<columnNum;i++){
            dataList.add(null);
        }
    }
    protected void setDataTable(DataTable dt){
        this.dt = dt;
    }

    /**
     * 废弃，此方法会暴露 datas 对象，可能会被直接修改，导致错误
     * 获取一行数据
     * @return
     */
//    public List<Object> getList(){
//        return datas;
//    }

    /**
     * 根据列名取出值
     * @param column
     * @return
     */
    public String getStringValue(String column){
        int index = dt.columns().getIndex(column);
        return getStringValue(index);
    }

    /**
     * 根据索引取出值
     * @param index
     * @return
     */
    public String getStringValue(int index){
        Object value = dataList.get(index);
        if(value == null){
            return null;
        }else if(value instanceof String) {
            return (String) value;
        }else{
            return value.toString();
        }
    }
//    public Byte getByteValue(String column){
//        Object value = getValue(column);
//        return (Byte)value;
//    }
//    public Byte getByteValue(int index){
//        Object value = datas.get(index);
//        return (Byte)value;
//    }

    public Integer getIntValue(String column){
        int index = dt.columns().getIndex(column);
        return getIntValue(index);
    }

    /**
     * 根据列索引取出值，并转成integer类型
     * @param index
     * @return
     */
    public Integer getIntValue(int index){
        Object value = dataList.get(index);
        if(value == null){
            return null;
        }else if(value instanceof Integer) {
            return (Integer) value;
        }else{ // 字符串、double类型
            return new Integer(value.toString());
        }
    }

    /**
     * 根据列名取出值
     * @param column
     * @return
     */
//    public Long getLongValue(String column){
//        Object value = getValue(column);
//        return (Long)value;
//    }
//
    /**
     * 根据索引取出值
     * @param index
     * @return
     */
//    public Long getLongValue(int index){
//        Object value = datas.get(index);
//        return (Long)value;
//    }
    /**
     * 根据列名取出值
     * @param column
     * @return
     */
    public Double getDoubleValue(String column){
        int index = dt.columns().getIndex(column);
        return getDoubleValue(index);
    }

    /**
     * 根据索引取出值，并转成 Double 类型
     * @param index
     * @return
     */
    public Double getDoubleValue(int index){
        Object value = dataList.get(index);
        if(value == null){
            return null;
        }else if(value instanceof Double) {
            return (Double) value;
        }else{// 字符串、Integer类型
            return new Double(value.toString());
        }
    }
    /**
     * 根据列名取出值
     * @param column
     * @return
     */
    public Object getValue(String column){
        int index = dt.columns().getIndex(column);
        Object value = dataList.get(index);
        return value;
    }

    /**
     * 根据索引取出值
     * @param index
     * @return
     */
    public Object getValue(int index){
        Object value = dataList.get(index);
        return value;
    }

    /**
     * 根据列索引设置数据
     *
     * 添加数据前，删除该记录的索引，
     * 对数据进行校验
     * 1. 如果列类型是 int 类型，不能添加 double 类型的值，可以添加 stirng类型（需要正确转成int）
     * 2. 如果列类型是 double 类型，可以添加 int 类型的值，可以添加 stirng类型（需要正确转成double）
     * 3. 如果列类型是 string 类型，可以添加 int、double 类型的值（需转string）
     * 4. 如果是 UNDEFINED ，不校验
     *
     * 添加该记录的索引
     * @param index 从0开始
     * @param data
     * @return
     */
    public DataRow setValue(int index,Object data){
        DataColumn dc = dt.columns().get(index);
        // 如果rowid不为null，说明已经添加，就先删除索引
        if(rowid != null) {
            dt.indexManager.remove(this,dc.getName());
        }

        Object newData = data;
        if(dc.getType() == DataColumn.Type.UNDEFINED){

        }else if(dc.getType() == DataColumn.Type.INT ){
            if( data instanceof Integer ){
                newData = data;
            }else if (data instanceof Double){
                throw new DataColumnTypeMismatchException(dc.getName(),dc.getType(),data);
            }else if (data instanceof String){
                newData = Integer.parseInt((String)data);
            }else if (data == null){
                newData = data;
            }else{
                throw new DataColumnTypeNotSupportedException(data);
            }
        }else if(dc.getType() == DataColumn.Type.DOUBLE ){
            if( data instanceof Integer ){
                newData = ((Integer)data).doubleValue();
            }else if (data instanceof Double){
                newData = data;
            }else if (data instanceof String){
                newData = Double.parseDouble((String)data);
            }else if (data == null){
                newData = data;
            }else{
                throw new DataColumnTypeNotSupportedException(data);
            }
        }else if(dc.getType() == DataColumn.Type.TEXT){
            if( data instanceof Integer || data instanceof Double){
                newData = data.toString();
            }else if (data instanceof String){
                newData = data;
            }else if (data == null){
                newData = data;
            }else{
                throw new DataColumnTypeNotSupportedException(data);
            }
        }

        dataList.set(index,newData);
        // 最后添加索引
        if(rowid != null) {
            dt.indexManager.save(this,dc.getName());
        }
        return this;
    }

    /**
     * 根据列名设置数据
     * @param columnName
     * @param data
     * @return
     */
    public DataRow setValue(String columnName,Object data){
        int index = dt.columns().getIndex(columnName);
        // 必须调用另一个方法，因为需要更新索引
        return setValue(index,data);
    }

    /**
     * 转成数组
     * @return
     */
    public Object[] toArray(){
        int size = dataList.size();
        Object[] array=new Object[size];

        return dataList.toArray(array);
    }

    protected DataTable getDataTable() {
        return dt;
    }

    @Override
    public String toString() {
        return "DataRow{" +
                "dataList=" + dataList +
                '}';
    }

    /**
     * 获取rowid
     * @return
     */
    public int getRowid() {
        return rowid;
    }
    /**
     * 添加行的时候，才设置行号
      */

    protected void setRowid(int rowid) {
        this.rowid = rowid;
    }
}
